//Linux C plus plus file
/************************************************************************
*
*
*       			FileName:utils.cpp
*
*         			Author.wzj
*
*       			Email:345517039@qq.com
*
*      	    		Create:2017-06-22 23:41:05
*
*      		    	Description:-
*
*
*************************************************************************/
#include "utils.h"
#include "server.h"

/**
 * @brief 当前支持的命令行注册函数,
 */
struct CmdFunctionSet Utils::CmdSet[] = {
	{CMD_1, Utils::displaySystemStatus, false },
	{CMD_2, Utils::setPthreadStackSize, true  },
	{CMD_3, Utils::setPthreadPolicy, true  }, 
	{CMD_4, Utils::displaySystemLog, false },
	{CMD_5, Utils::setSystemLogLevel, true },
	{CMD_6, Utils::displayThreadIdStatus, true },
	{CMD_7, Utils::restart , false },
	{CMD_8, Utils::quit, false },
	{CMD_9, Utils::help, false },
	{ 0, NULL, false }
};

/*@brief help命令函数
 *
 *
 */
int Utils::help(void *arg){
	fprintf(stderr,"========================= SYSTEM  CMD ==============================\n");
	fprintf(stderr,"#display-system-status\n");
	fprintf(stderr,"#set-pthread-stack-size-#\n");
	fprintf(stderr,"#set-pthread-policy-#\n");
	fprintf(stderr,"#display-system-log\n");
	fprintf(stderr,"#set-system-log-level-#\n");
	fprintf(stderr,"#restart\n");
	fprintf(stderr,"#quit\n");
	fprintf(stderr,"#help\n");
	fprintf(stderr,"=====================================================================\n");
	return RET::SUCCESS;
}



/**
 * @brief  注册命令行函数初始化
 *
 * @return 
 */
int Utils::registerCmdFunctionInit()
{
	int i = 0;
	cmdHash.clear();
	for( ; CmdSet[i].index != 0; i++ )
	{
		cmdHash.insert(std::pair<int, struct CmdFunctionSet>(CmdSet[i].index, CmdSet[i]));
	}
	return RET::SUCCESS;
}

/*@brief:
 *
 *
 */
int Utils::quit(void *arg){
	DEBUG_TRACE(2,("[ INFO ]QUIT SYSTEM!!!\n"));
	return RET::SUCCESS;
}


/**
 * @brief  注册显示系统状态的命令行
 *
 * @return 
 */
int Utils::displaySystemStatus(void *arg){
	std::cout <<"[ INFO ]DISPLAY SYSTEM STATUS " << std::endl;
	return RET::SUCCESS;
}


/**
 * @brief 注册设置线程栈区大小的命令行
 *
 * @return 
 */
int Utils::setPthreadStackSize(void *arg){
	std::cout <<"[ INFO ]SET PTHREAD STACK SIZE "<< std::endl;

	return RET::SUCCESS;
}



/**
 * @brief 注册设置线程调度策略的命令行
 *
 * @param arg
 *
 * @return 
 */
int Utils::setPthreadPolicy(void *arg){
	std::cout <<"[ INFO ]SET PTHREAD POLICY "<< std::endl;
	return  RET::SUCCESS;
}



/**
 * @brief 注册显示系统日志的命令行回调函数
 *
 * @return 
 */
int Utils::displaySystemLog(void *arg){
	std::cout <<"[ INFO ]DISPLAY SYSTEM LOG "<< std::endl;

	return RET::SUCCESS;
}



/**
 * @brief 注册设置系统日志级别的回调函数
 *
 * @return 
 */
int Utils::setSystemLogLevel(void *arg){
	std::cout <<"[ INFO ]SET SYSTEM LOG LEVEL "<< std::endl;

	return RET::SUCCESS;
}


/**
 * @brief 注册显示线程ID状态
 *
 * @param arg
 *
 * @return 
 */
int Utils::displayThreadIdStatus(void *arg){
	std::cout <<"[ INFO ]DISPLAY THREAD ID STATUS"<< std::endl;

	return RET::SUCCESS;
}


/**
 * @brief 重启回调函数
 *
 * @return 
 */
int Utils::restart(void *arg){
	std::cout <<"[ INFO ]RESTART "<< std::endl;

	return RET::SUCCESS;
}




/**
 * @brief 
 *
 * @param ipaddr
 *
 * @return 
 */
int Utils::isIpv4(const char *ipaddr){
	int ip[4]={0};
	sscanf(ipaddr,"%d.%d.%d.%d",ip,ip+1,ip+2,ip+3);
	//判断合法性
	for(int i = 0; i < 4; i++){
		if(i == 0 || i == 3){
			if(ip[i] <= 0 || ip[i]>=255){
				return RET::FAIL;
			}
		}else{
			if(ip[i]>=255){
				return RET::FAIL;
			}
		}
	}
	return RET::SUCCESS;
}


/**
 * @brief 
 *
 * @param portaddr
 * @param port
 *
 * @return 
 */
int Utils::isPort(char *portaddr,std::vector<char *> &port){
	const char * delim = ";";
	char * pPort = strtok(portaddr, delim);
	if(!pPort){
		std::cout << "null" << std::endl;
		return RET::FAIL;
	}
	port.push_back(pPort);
	while((pPort = strtok(NULL, delim))){
		port.push_back(pPort);
	}
	return RET::SUCCESS;
}


/**
 * @brief 
 *
 * @param path
 *
 * @return 
 */
int Utils::pathIsReadable(const char * path){
	int ret = access(path,R_OK);
	return ret;
}


/**
 * @brief 
 *
 * @param fd
 *
 * @return 
 */
int Utils::setFdNonblock(int  fd){
	short flag = 0;
	int ret = fcntl(fd, F_GETFL, flag);
	ret = fcntl(fd, F_SETFL, flag|O_NONBLOCK);
	if(ret == 0){
		fprintf(stderr, "set fd nonblock fail!\n");
		return -1;
	}
	return ret;
}



/**
 * @brief 格式化命令
 *
 * @param pCmd
 * @param pBuf
 *
 * @return 
 */
int Utils::FormatCmd(char *pCmd, char *pBuf){
	int iRet = RET::FAIL;

	if ( NULL == pCmd || pCmd[0] == '\n' || NULL == pBuf ){
		return iRet;
	}
	pBuf[0] = 0x0;

	char * p = NULL;
	size_t len = strlen(pCmd);

	char pSrcCmd[len+1];
	memset(pSrcCmd, '\0', len+1);
	memcpy(pSrcCmd, pCmd, len);
	unsigned int i = 0;
	for ( i = 0; i < len; i++ ){
		if (isprint(pSrcCmd[i])&&!isspace(pSrcCmd[i])){
			if ( NULL ==  p){
				p = pSrcCmd + i;
			}
		}
		
		if (isspace(pSrcCmd[i])&& p){
			pSrcCmd[i] = 0x0;
			sprintf(pBuf + strlen(pBuf), "%s", p );
			p = NULL;
		}
	}
	if ( p != NULL ){
		sprintf(pBuf + strlen(pBuf), "%s", p );
		p = NULL;
	}
	
	if(pBuf[0]){
		//在这边在对pBuf的命令进行格式判断;
		if(pBuf[0] == '-'  || pBuf[ strlen(pBuf)-1 ] == '-'){
			return RET::FAIL;
		}
		//然后就是判断命令中间有没有连续的--
		i = 0;
		while(pBuf[i]!='\0'){
			if (pBuf[i] == '-' && pBuf[i+1] == '-'){
				return RET::FAIL;
			}
			i++;
		}
		return RET::SUCCESS;
	}else
		return RET::FAIL;
}





